﻿using System;
using System.IO.Ports;
using System.Threading;

class SerialCommunication
{
    static SerialPort serialPort;

    static void Main()
    {
        // 显示可用串口列表
        string[] availablePorts = SerialPort.GetPortNames();
        if (availablePorts.Length == 0)
        {
            Console.WriteLine("未找到可用的串口，请检查设备连接。");
            return;
        }

        Console.WriteLine("可用的串口列表：");
        foreach (string port in availablePorts)
        {
            Console.WriteLine(port);
        }

        // 让用户输入串口名称
        string portName = GetValidPortName(availablePorts);

        // 配置串口参数
        serialPort = new SerialPort();
        serialPort.PortName = portName;
        serialPort.BaudRate = 9600;
        serialPort.DataBits = 8;
        serialPort.Parity = Parity.None;
        serialPort.StopBits = StopBits.One;

        try
        {
            // 打开串口
            serialPort.Open();
            Console.WriteLine("串口已打开");

            // 启动接收线程
            Thread receiveThread = new Thread(ReceiveData);
            receiveThread.Start();

            // 发送数据
            SendDataLoop();
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine("无法访问该串口，可能已被其他程序占用。");
        }
        catch (System.IO.IOException)
        {
            Console.WriteLine("串口通信出现 I/O 错误，请检查设备连接。");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"串口通信错误: {ex.Message}");
        }
        finally
        {
            // 关闭串口
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
            Console.WriteLine("串口已关闭");
        }
    }

    static string GetValidPortName(string[] availablePorts)
    {
        string portName;
        while (true)
        {
            Console.Write("请输入要使用的串口名称（从上述列表中选择）：");
            portName = Console.ReadLine().Trim();
            if (Array.IndexOf(availablePorts, portName) != -1)
            {
                break;
            }
            Console.WriteLine("输入的串口名称无效，请重新输入。");
        }
        return portName;
    }

    static void SendDataLoop()
    {
        while (true)
        {
            Console.Write("（输入 'q' 退出）：");
            string message = Console.ReadLine().Trim();
            if (message.ToLower() == "q")
            {
                break;
            }
            if (string.IsNullOrEmpty(message))
            {
                Console.WriteLine("输入的消息不能为空，请重新输入。");
                continue;
            }
            try
            {
                string sentTime = $"[SENT {DateTime.Now:yyyy-MM-dd HH:mm:ss}] ";
                string formattedMessage = sentTime + message;
                serialPort.WriteLine(formattedMessage);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("串口未打开，无法发送数据。");
                break;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送数据时出错: {ex.Message}");
            }
        }
    }

    static void ReceiveData()
    {
        while (true)
        {
            try
            {
                if (serialPort.BytesToRead > 0)
                {
                    string recvData = serialPort.ReadLine().Trim();
                    string recvTime = $"[RECV {DateTime.Now:yyyy-MM-dd HH:mm:ss}] ";
                    Console.WriteLine(recvTime + recvData);
                }
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("串口未打开，无法接收数据。");
                break;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"接收数据错误: {ex.Message}");
                break;
            }
        }
    }
}